'use strict';
d3.chart = d3.chart || {};
d3.chart.architectureTree = function () {
    var svg, tree, treeData, diameter, activeNode;

    /**
     * Build the chart
     */
    function chart() {
        if (typeof(tree) === 'undefined') {
            tree = d3.layout.tree()
                .size([360, diameter / 2 - 120])
                .separation(function (a, b) {
                    return (a.parent == b.parent ? 1 : 2) / a.depth;
                });
            svg = d3.select("#graph").append("svg")
                .attr("width", diameter)
                .attr("height", diameter)
                .append("g")
                .attr("transform", "translate(" + diameter / 2 + "," + diameter / 2 + ")");
        }
        var nodes = tree.nodes(treeData),
            links = tree.links(nodes);
        nodes.forEach(function (d) {
            d.y = d.depth * 120;
        });
        activeNode = null;
        svg.call(updateData, nodes, links);
    }

    var drag = d3.behavior.drag()
        .origin(function (d, i) {
            console.log(d);
            return {x: d.cx, y: d.cy}
        })
        .on("dragstart", function (d) {
            console.log("拖拽开始");
        })
        .on("dragend", function (d) {
            console.log("拖拽开始");
        })
        .on("drag", function (d) {
            d3.select(this)
                .attr("cx", d.cx = d3.event.x)
                .attr("cy", d.cy = d3.event.y);
        });
    /**
     * Update the chart data
     * @param {Object} container
     * @param {Array}  nodes
     */
    var updateData = function (container, nodes, links) {

        // Enrich data
        //addDependents(nodes);
        nodes.map(function (node) {
            addIndex(node);
        });
        var diagonal = d3.svg.diagonal.radial()
            .projection(function (d) {
                return [d.y, d.x / 180 * Math.PI];
            });
        var linkSelection = svg.selectAll(".link").data(links, function (d) {
                return d.source.name + d.target.name + Math.random();
            }
        );
        linkSelection.exit().remove();
        linkSelection.enter().append("path")
            .attr("class", "link")
            .attr("d", diagonal)
            .style('stroke', function (d) {
                return d3.scale.linear()
                    //.domain([1, 0])
                    .range(["#eee", "#ff00ff"])(0);
            });
        var colors = ["#ff0000", "#3d4rfg"];
        var nodeSelection = container.selectAll(".node").data(nodes, function (d) {
            return d.name + Math.random();  // always update node
        });
        nodeSelection.exit().remove();
        var node = nodeSelection.enter().append("g")
            .attr("class", "node")
            .attr("transform", function (d) {
                return "rotate(" + (d.x - 90) + ")translate(" + d.y + ")";
            })
            .on('mouseover', function (d) {
                if (activeNode !== null) {
                    return;
                }
                fade(0.2)(d);
                //document.querySelector('#panel').dispatchEvent(
                //    new CustomEvent("hoverNode", {"detail": d.name})
                //);
            })
            .on('mouseout', function (d) {
                if (activeNode !== null) {
                    return;
                }
                fade(1)(d);
            })
            .on('click', function (d) {
                select(d.name);
                paneldetail(d.id);
            });
        node.append("circle")
            .attr("r", function (d) {
                return 4.5 * (d.size || 1);
            })
            .style('stroke', function (d) {
                return d3.scale.linear()
                    //.domain([1, 0])
                    .range(["steelblue", "#ff00ff"])(0);
            })
            .style('fill', function (d) {
                if (typeof d.satisfaction === "undefined") return '#fff';
                return d3.scale.linear()
                    .domain([1, 0])
                    .range(["white", "#f66"])(0);
            });
        node.append("text")
            .attr("dy", ".31em")
            .attr("text-anchor", function (d) {
                return d.x < 180 ? "start" : "end";
            })
            .attr("transform", function (d) {
                return d.x < 180 ? "translate(8)" : "rotate(180)translate(-8)";
            })
            .text(function (d) {
                return d.name;
            });
        //.style('fill', function (d) {
        //if (typeof d.satisfaction === "undefined") return '#fff';
        //return colors[0];
        //});
    };
    /**
     * Add indices to a node, including inherited ones.
     *
     * Mutates the given node (datum).
     *
     * Example added properties:
     * {
     *   index: {
     *     relatedNodes: ["Foo", "Bar", "Baz", "Buzz"],
     *     technos: ["Foo", "Bar"],
     *     host: ["OVH", "fo"]
     *   }
     * }
     */
    var addIndex = function (node) {
        node.index = {
            relatedNodes: [],
            comtags: []
            //basics: []
        };
        var comtags = getDetailCascade(node, 'tags');
        if (comtags.length > 0) {
            node.index.comtags = comtags;
        }
        //var basics = getDetailCascade(node, 'basic');
        //if (basics.length > 0) {
        //    node.index.basics = basics;
        //}
    };
    var getDetailCascade = function (node, detailName) {
        var values = [];
        if (node[detailName]) {
            node[detailName].forEach(function (value) {
                values.push(value);
            });
        }
        if (node.parent) {
            values = values.concat(getDetailCascade(node.parent, detailName));
        }
        return values;
    };
    var getHostsCascade = function (node) {
        var values = [];
        if (node.host) {
            for (var i in node.host) {
                values.push(i);
            }
        }
        if (node.parent) {
            values = values.concat(getHostsCascade(node.parent));
        }
        return values;
    };
    var fade = function (opacity) {
        return function (node) {
            svg.selectAll(".node")
                .filter(function (d) {
                    if (node.children) {
                        for (var i in node.children) {
                            if (d.name === node.children[i].name) return false;
                        }
                    }
                    if (node.parent) {
                        if (d.name === node.parent.name) return false;
                    }
                    if (d.name === node.name) return false;
                    return node.index.relatedNodes.indexOf(d.name) === -1;
                })
                .transition()
                .style("opacity", opacity);
        };
    };
    var filters = {
        comtags: []
        //basics: []
    };
    var isFoundByFilter = function (d) {
        var i;
        if (!filters.comtags.length) {
            // nothing selected
            return true;
        }
        var tagsCount = filters.comtags.length;
        if (tagsCount) {
            if (d.index.comtags.length === 0) return false;
            for (i = 0; i < tagsCount; i++) {
                if (d.index.comtags.indexOf(filters.comtags[i]) === -1) return false;
            }
        }
        //var basicCount = filters.basics.length;
        //if (basicCount) {
        //    if (d.index.basics.length === 0) return false;
        //    for (i = 0; i < basicCount; i++) {
        //        if (d.index.basics.indexOf(filters.basics[i]) === -1) return false;
        //    }
        //}
        return true;
    };
    var refreshFilters = function () {
        d3.selectAll('.node').classed('notFound', function (d) {
            return !isFoundByFilter(d);
        });
    };
    var select = function (name) {
        if (activeNode && activeNode.name == name) {
            unselect();
            return;
        }
        unselect();
        svg.selectAll(".node")
            .filter(function (d) {
                if (d.name === name) return true;
            })
            .each(function (d) {
                //document.querySelector('#panel').dispatchEvent(
                //    new CustomEvent("selectNode", {"detail": d.name})
                //);
                d3.select(this).attr("id", "node-active");
                activeNode = d;
                fade(0.1)(d);
            });
    };
    var unselect = function () {
        if (activeNode == null) return;
        fade(1)(activeNode);
        d3.select('#node-active').attr("id", null);
        activeNode = null;
        //document.querySelector('#panel').dispatchEvent(
        //    new CustomEvent("unSelectNode")
        //);
    };
    chart.select = select;
    chart.unselect = unselect;
    chart.data = function (value) {
        if (!arguments.length) return treeData;
        treeData = value;
        return chart;
    };
    chart.diameter = function (value) {
        if (!arguments.length) return diameter;
        diameter = value;
        return chart;
    };
    //chart.nameFilter = function (nameFilter) {
    //    filters.name = nameFilter;
    //    refreshFilters();
    //};
    chart.tagsFilter = function (technosFilter) {
        filters.comtags = technosFilter;
        refreshFilters();
    };
    var paneldetail = function (id) {
        $.ajax({
            url: "/",
            async: false, // 注意此处需要同步
            type: "POST",
            dataType: "json",
            data: {
                id: id
            },
            success: function (data) {
            }
        });
    };
    //chart.basicFilter = function (basicFilter) {
    //    filters.basics = basicFilter;
    //    refreshFilters();
    //};
    return chart;
};
